package com.cctc.rds.raft.core.log.commit;

import com.cctc.rds.raft.core.log.Log;
import com.cctc.rds.raft.core.log.LogService;
import com.cctc.rds.raft.core.log.commit.statemachine.StateMachine;

/**
 * 日志条目提交器。
 * - 实现日志条目 -> 应用状态机的胶水类。
 */
public class LogCommitter {
    private LogService logService;
    private StateMachine stateMachine;

    public LogCommitter(LogService logService, StateMachine stateMachine) {
        this.logService = logService;
        this.stateMachine = stateMachine;
    }

    /**
     * 提交日志条目。
     * - 更新日志条目的状态为已应用；
     * - 将日志条目应用到具体的应用状态机。
     */
    public boolean commit(Log log) {
        if (log != null) {
            log.setStatus(1);
            logService.update(log);
            return stateMachine.apply(log);
        }
        return false;
    }

    /**
     * 获取最新的提交日志索引。
     */
    public long maxCommitLogIndex() {
        Log log = logService.peek();
        if (log == null) return -1;
        if (log.getStatus() == 1) return log.getIndex();
        long prevCommitLogIndex = log.getIndex() - 1;
        while (prevCommitLogIndex >= 0) {
            log = logService.index(prevCommitLogIndex);
            if (log.getStatus() == 1) return log.getIndex();
            prevCommitLogIndex--;
        }
        return -1;
    }

}
